/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under Ultimate Liberty license
  * SLA0044, the "License"; You may not use this file except in compliance with
  * the License. You may obtain a copy of the License at:
  *                             www.st.com/SLA0044
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "dma.h"
#include "i2c.h"
#include "tim.h"
#include "usart.h"
#include "usb_device.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
FlagStatus LedSW=RESET,UsartSW=RESET,KeepStop=RESET,Auto=RESET;
uint8_t ledCount=0;
uint8_t commandBuff[8];
uint32_t adc_Value[2];
uint16_t battery_Value =0;
uint16_t speedValue,dirValue,speedInt,dirInt;
int speedPWM,dirPWM;
uint16_t step=0;
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
void KEEPSTOP(void);
void UNKEEPSTOP(void);
void RockInit(void);
void GetADC(void);
void GetBattery(void);
void Control(void);
void PACK(void);
void AutoDriver(void);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
    /* USER CODE BEGIN 1 */

    /* USER CODE END 1 */


    /* MCU Configuration--------------------------------------------------------*/

    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    HAL_Init();

    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* Configure the system clock */
    SystemClock_Config();

    /* USER CODE BEGIN SysInit */

    /* USER CODE END SysInit */

    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_DMA_Init();
    MX_ADC1_Init();
    MX_I2C1_Init();
    MX_USART1_UART_Init();
    MX_USB_DEVICE_Init();
    MX_TIM2_Init();
    MX_ADC2_Init();
    /* USER CODE BEGIN 2 */

    HAL_ADC_Start_DMA(&hadc1,adc_Value,2);
    HAL_TIM_Base_Start_IT(&htim2);
    RockInit();
    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
        if(LedSW)
        {
            LedSW=RESET;
            HAL_GPIO_TogglePin(USERLED1_GPIO_Port, USERLED1_Pin);
            GetBattery();
        }


        if(HAL_GPIO_ReadPin(KEY3_GPIO_Port,KEY3_Pin)==0)
        {
            Auto=RESET;
            KEEPSTOP();
        }
        if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==0)
        {
            UNKEEPSTOP();

        }
        if(HAL_GPIO_ReadPin(KEY4_GPIO_Port,KEY4_Pin)==0)
        {

            Auto=SET;
        }

        if(UsartSW)
        {
            if(Auto)
            {
                UsartSW=RESET;
                AutoDriver();
                HAL_UART_Transmit(&huart1,commandBuff,8,2);
            } else
            {
                UsartSW=RESET;
                GetADC();
                Control();
                HAL_UART_Transmit(&huart1,commandBuff,8,2);
            }
        }
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
    }
    /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

    /** Initializes the CPU, AHB and APB busses clocks
    */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        Error_Handler();
    }
    /** Initializes the CPU, AHB and APB busses clocks
    */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                  |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
    {
        Error_Handler();
    }
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC|RCC_PERIPHCLK_USB;
    PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
    PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
        Error_Handler();
    }
}

/* USER CODE BEGIN 4 */
void KEEPSTOP()
{
    KeepStop=SET;
    commandBuff[2]=0x55;
}
void UNKEEPSTOP()
{
    KeepStop=RESET;
    commandBuff[2]=0xAA;
}
void PACK()
{
    commandBuff[2]=0xCC;
}
void RockInit()
{
    HAL_Delay(100);
    dirInt =(uint16_t)adc_Value[0];
    speedInt =(adc_Value[0]>>16);
}

void GetADC()
{
    dirPWM=(((uint16_t)adc_Value[0])-dirInt)/10;
    speedPWM=((adc_Value[0]>>16)/10)-((speedInt)/10);
}
void Control()
{
    if(speedPWM>-70&&speedPWM<70)
    {
        commandBuff[3]=0x00;

    } else if(speedPWM>70)
    {
        commandBuff[3]=0x11;
    } else if(speedPWM<-70)
    {
        commandBuff[3]=0x22;
    }
    if(dirPWM>-70&&dirPWM<70)
    {
        commandBuff[5]=0x00;
    } else if(dirPWM>70)
    {
        commandBuff[5]=0x22;
    } else if(dirPWM<-70)
    {
        commandBuff[5]=0x11;
    }

    speedPWM=abs(speedPWM);
    dirPWM=abs(dirPWM);
    commandBuff[0]=0xAA;
    commandBuff[1]=0x55;
    commandBuff[4]=(uint8_t)speedPWM/2;
    commandBuff[6]=(uint8_t)dirPWM/2;

}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == htim2.Instance)
    {
        UsartSW=SET;
        step++;
        if(step>2500)
        {
            step=0;
        }
        if(ledCount<5)
        {
            ledCount++;
        } else
        {
            ledCount=0;
            LedSW=SET;
        }


    }
}
void GetBattery(void)
{
    HAL_ADC_Start(&hadc2);
    HAL_ADC_PollForConversion(&hadc2, 50);
    battery_Value = HAL_ADC_GetValue(&hadc2);
}
void AutoDriver()
{
    commandBuff[0]=0xAA;
    commandBuff[1]=0x55;
    commandBuff[2]=0xAA;
    commandBuff[4]=200;
    commandBuff[6]=200;
    if(step<600)
    {
        commandBuff[3]=0x11;
        commandBuff[5]=0x00;
    } else if(step>600&&step<1200)
    {
        commandBuff[3]=0x22;
        commandBuff[5]=0x00;
    } else if(step>1200&&step<1800)
    {
        commandBuff[3]=0x00;
        commandBuff[5]=0x22;
    } else if(step>1800&&step<2400)
    {
        commandBuff[3]=0x00;
        commandBuff[5]=0x11;
    }
}


/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
    /* USER CODE BEGIN Error_Handler_Debug */
    /* User can add his own implementation to report the HAL error return state */

    /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
    /* USER CODE BEGIN 6 */
    /* User can add his own implementation to report the file name and line number,
       tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
